using BlazorAdmin.Interface;
using BlazorAdmin.Models;
using BlazorAdmin.Models.Dto;
using BlazorAdmin.Tcp.Server;
using BlazorAdmin.Web.Shared.Components;
using BlazorAdmin.Web.Shared.Models;
using BlazorAdmin.Web.Shared.Services;
using BootstrapBlazor.Components;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;
using Newtonsoft.Json;
using Pangeo.Admin.Models;

namespace BlazorAdmin.Web.Shared.Pages.Admin
{
    /// <summary>
    /// DeviceManager.razor 页面代码
    /// </summary>
    public partial class DeviceManager
    {
        private AdminTable<Device>? Table;

        private string? SelectedOrgCode { get; set; }

        private DialogOption? Option { get; set; }

        private List<TreeViewItem<Organize>>? OrganizeTree { get; set; }

        public ITableSearchModel TableSearchModel { get; } = new DeviceSearchModel();

        private bool HasConnection(Device item) => HasConnection(item.Guid);

        private bool HasConnection(string guid) => TcpServer.GetConnections(t => t.ID == guid).Any();

        private IEnumerable<DeviceTcpToken>? GetConnections(string guid) => TcpServer.GetConnections(t => t.ID == guid);

        private static readonly JsonSerializerSettings jsonSettings = new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore };

        protected override async Task OnInitializedAsync()
        {
            TypeItems = DictService.GetByCategory(Consts.DeviceType);

            OrganizeTree = await OrganizeService?.GetOrganizeTree(AppContext?.LoginName);

            // 默认选中未分组
            OrganizeTree[0].CheckedState = CheckboxState.Checked;
            SelectedOrgCode = OrganizeTree[0].Value.OrgCode;
        }

        /// <summary>
        /// 批量下发信息同步指令
        /// </summary>
        private async Task BatchSendSyncInfoCmd(IEnumerable<Device> items)
        {
            if (items.Count() == 0)
            {
                MsgService?.Show(new() { Content = "请选择客户端" });
                return;
            }

            items.ToList().ForEach(async device => await SendSyncInfoCmd(device));

            Table?.QueryAsync();
        }

        /// <summary>
        /// 下发信息同步指令
        /// </summary>
        private async Task<bool> SendSyncInfoCmd(Device device)
        {
            var conn = TcpServer?.GetConnections(t => t.ID == device.Guid).FirstOrDefault();
            if (conn != null)
            {
                // 下发同步指令客户端 => 客户端更新设备信息
                TcpServer?.Send(JsonConvert.SerializeObject(new TcpSignal() { 
                    IsUpdate = true
                }, jsonSettings), conn);

                MsgService?.Show(new MessageOption { Content = $"{device.IP} 下发同步指令成功", Color = Color.Success });
            }
            else
            {
                MsgService?.Show(new MessageOption { Content = $"{device.IP} 已离线，无法下发同步指令", Color = Color.Danger });
            }

            return true;
        }

        /// <summary>
        /// 批量下发备份指令
        /// </summary>
        private async Task BatchSendBackupCmd(IEnumerable<Device> items)
        {
            if (items.Count() == 0)
            {
                MsgService?.Show(new() { Content = "请选择客户端" });
                return;
            }

            items.ToList().ForEach(async device => await SendBackupCmd(device));

            Table?.QueryAsync();
        }

        /// <summary>
        /// 下发备份指令
        /// </summary>
        private async Task<bool> SendBackupCmd(Device device)
        {
            var conn = TcpServer?.GetConnections(t => t.ID == device.Guid).FirstOrDefault();
            if (conn != null)
            {
                TcpServer?.Send(JsonConvert.SerializeObject(new
                {
                    IsBackup = true
                }, jsonSettings), conn);

                MsgService?.Show(new MessageOption { Content = $"{device.IP} 下发备份指令成功", Color = Color.Success });
            }
            else
            {
                MsgService?.Show(new MessageOption { Content = $"{device.IP} 已离线，无法下发备份指令", Color = Color.Danger });
            }

            return true;
        }

        private string PopDeviceInfo(Device item)
        {
            var tip = $"<div>IP : {(HasConnection(item.Guid) ? $"<span class='bold-green'>{item.IP}</span>" : item.IP)}</div>";
            tip += $"<div>Mac : {(string.IsNullOrEmpty(item.Mac) ? "---" : item.Mac)}</div>";
            tip += $"<div>Host : {(string.IsNullOrEmpty(item.Host) ? "---" : item.Host)}</div>";
            tip += $"<div>OS : {(string.IsNullOrEmpty(item.OS) ? "---" : item.OS)}</div>";
            tip += $"<div>ID : {(string.IsNullOrEmpty(item.Guid) ? "---" : item.Guid)}</div>";

            if (!string.IsNullOrEmpty(item.Location))
                tip += $"<div>Site : {item.Location}</div>";

            return tip;
        }

        /// <summary>
        /// 分页查询
        /// </summary>
        private async Task<QueryData<Device>>? OnQueryAsync(QueryPageOptions options)
        {
            var query = new AppQueryOption<string>(options, AppContext?.LoginName);

            if (!string.IsNullOrWhiteSpace(options.SearchText) || options.CustomerSearches.Count > 0)
                query.Param = "custome_search";  // 快速搜索、高级搜索
            else
                query.Param = SelectedOrgCode; // 查询未分组、已分组的

            return await DeviceService?.Query(query);
        }

        /// <summary>
        /// 保存
        /// </summary>
        private async Task<bool> OnSaveAsync(Device device, ItemChangedType type)
        {
            var errMsg = await DeviceService.Save(device);

            if (string.IsNullOrEmpty(errMsg))
            {
                var conn = TcpServer?.GetConnections(t => t.ID == device.Guid).FirstOrDefault();
                if (conn != null)
                {
                    // 保存信息至客户端（不需要客户端上报设备信息）
                    TcpServer?.Send(JsonConvert.SerializeObject(new TcpSignal()
                    {
                        AssetNo = device.AssetNo,
                        Location = device.Location,
                        BackupPath = device.BackupDir,
                        UploadedPath = device.UploadPath
                    }, jsonSettings), conn);
                }

                return true;
            }
            else
            {
                MsgService?.Show(new()
                {
                    Icon = "fa-solid fa-circle-info",
                    Content = errMsg,
                    Color = Color.Danger
                });

                return false;
            }
        }

        /// <summary>
        /// 删除
        /// </summary>
        private async Task<bool> OnDeleteAsync(IEnumerable<Device> items)
        {
            if(items.Count() == 0)
            {
                MsgService?.Show(new()
                {
                    Icon = "fa-solid fa-circle-info",
                    Content = "请选择要删除的客户端",
                    Color = Color.Warning
                });

                return false;
            }

            var isSuccess = await DeviceService.Delete(items.Select(t => t.ID).ToList());
            if(isSuccess)
                MsgService?.Show(new() { Content = "删除成功！" });
            else
                MsgService?.Show(new()
                {
                    Icon = "fa-solid fa-circle-info",
                    Content = "删除失败",
                    Color = Color.Danger
                });

            Table.QueryAsync();

            return isSuccess;
        }

        /// <summary>
        /// 分配组织
        /// </summary>
        private async Task MoveOrganize(IEnumerable<Device> items)
        {
            if (items.Count() == 0)
            {
                MsgService?.Show(new() { Content = "请选择客户端" });
                return;
            }

            Option = new DialogOption()
            {
                Title = "选择设备组",
                IsScrolling = true,
                Size = Size.Medium,
                BodyTemplate = BootstrapDynamicComponent.CreateComponent<TreeView<Organize>>(new Dictionary<string, object?>
                {
                    [nameof(TreeView<Organize>.ShowIcon)] = true,
                    [nameof(TreeView<Organize>.ShowSkeleton)] = true,
                    [nameof(TreeView<Organize>.Items)] = OrganizeTree,
                    [nameof(TreeView<Organize>.OnTreeItemClick)] = async (TreeViewItem<Organize> item) => SelectedOrgCode = item.Value.OrgCode
                }).Render(),
                FooterTemplate = BootstrapDynamicComponent.CreateComponent<Button>(new Dictionary<string, object?>
                {
                    [nameof(Button.Color)] = Color.Primary,
                    [nameof(Button.Text)] = "确认",
                    [nameof(Button.Icon)] = "fa-solid fa-fw fa-check",
                    [nameof(Button.OnClick)] = EventCallback.Factory.Create<MouseEventArgs>(this, async () =>
                    {
                        if (SelectedOrgCode.ToLower() != "default") // 正常分组
                        {
                            await DeviceService.BatchInsert(SelectedOrgCode, items.Select(t => t.ID).Distinct().ToList());
                        }
                        else if (SelectedOrgCode.ToLower() == "default") // 未分组（撤销分组）
                        {
                            await DeviceService.BatchDelete(items.Select(t => t.ID).ToList());
                        }
                        else
                        {
                            MsgService?.Show(new() { Content = "请选择设备组" });
                            return;
                        }

                        MsgService?.Show(new() { Content = "操作成功！" });

                        Table.QueryAsync();
                        Option.CloseDialogAsync();

                    })
                }).Render()
            };

            await DialogService.Show(Option);
        }

        private async Task OnOrganizeClick(TreeViewItem<Organize> item)
        {
            if (SelectedOrgCode != item.Value.OrgCode) // 发生改变之后，重新查询
            {
                SelectedOrgCode = item.Value.OrgCode;

                Table.Context.SearchText = null; // 清空快速搜索
                Table.Context.CustomerSearchModel?.Reset(); // 清空高级搜索
                Table.QueryAsync();
            }
        }

        #region Items 字典数据

        private List<SelectedItem> TypeItems { get; set; }

        #endregion

        #region Inject 注入的服务

        [Inject]
        private BootstrapAppContext? AppContext { get; set; }

        [Inject]
        private DialogService? DialogService { get; set; }

        [Inject]
        private MessageService? MsgService { get; set; }

        [Inject]
        private IDevice? DeviceService { get; set; }

        [Inject]
        private IOrganize? OrganizeService { get; set; }

        [Inject]
        private TcpServer<DeviceTcpToken>? TcpServer { get; set; }

        [Inject]
        private IDict? DictService { get; set; }

        #endregion
    }
}
